home *** CD-ROM | disk | FTP | other *** search
- /*
- * A sample color picker.
- *
- * Written by: Shannon Holland
- * March 2, 1992
- *
- */
-
- #define SystemSevenOrLater 1
-
- #include <Memory.h>
- #include <Sysequ.h>
- #include <QDOffscreen.h>
- #include <FixMath.h>
- #include <ToolUtils.h>
- #include <SANE.h>
- #include <Resources.h>
- #include <Controls.h>
- #include <Windows.h>
- #include <Dialogs.h>
- #include <Timer.h>
- #include <Packages.h>
- #include <strings.h>
- #include <TextEdit.h>
- #include <Fonts.h>
- #include <Script.h>
- #include <GestaltEqu.h>
- #include <CMApplication.h>
-
- #include "ColorPicker.h"
- #include "ColorPickerComponentPublic.h"
- #include "Example.h"
-
-
-
- #define RectWidth(x) ((x).right - (x).left)
- #define RectHeight(x) ((x).bottom - (x).top)
- #define ChangeBigEnough(x,y) (abs(x - y) > 6)
-
- /*
- * Determine which routine to dispatch to and then ask the component manager to call that
- * routine with our storage handle and all of its parameters set up nicely.
- */
- pascal ComponentResult ExampleMain(ComponentParameters *params, Handle storage)
- {
- short message;
- ComponentResult result;
- ComponentFunction RoutineToCall = 0;
-
- message = params->what;
- if (message < 0)
- // negative values are component manager messages
- switch (message)
- {
- case kComponentOpenSelect: RoutineToCall=ExampleOpen; break;
- case kComponentCloseSelect: RoutineToCall=ExampleClose; break;
- case kComponentCanDoSelect: RoutineToCall=ExampleCanDo; break;
- case kComponentVersionSelect: RoutineToCall=ExampleVersion; break;
- case kComponentRegisterSelect: RoutineToCall=ExampleRegister; break;
- case kComponentTargetSelect: RoutineToCall=ExampleSetTarget; break;
- default: return 0; // no error
- }
- else
- {
- switch (message)
- {
- case kInitPicker: RoutineToCall=ExampleInitPicker; break;
- case kTestGraphicsWorld: RoutineToCall=ExampleTestGraphicsWorld; break;
- case kGetDialog: RoutineToCall=ExampleGetDialog; break;
- case kGetItemList: RoutineToCall=ExampleGetItemList; break;
- case kGetColor: RoutineToCall=ExampleGetColor; break;
- case kSetColor: RoutineToCall=ExampleSetColor; break;
- case kEvent: RoutineToCall=ExampleDoEvent; break;
- case kEdit: RoutineToCall=ExampleDoEdit; break;
- case kSetVisibility: RoutineToCall=ExampleSetVisibility; break;
- case kDrawPicker: RoutineToCall=ExampleDisplayPicker; break;
- case kItemHit: RoutineToCall=ExampleItemHit; break;
- case kSetBaseItem: RoutineToCall=ExampleSetBaseItem; break;
- case kGetProfile: RoutineToCall=ExampleGetProfile; break;
- case kSetProfile: RoutineToCall=ExampleSetProfile; break;
- case kGetPrompt: RoutineToCall=ExampleGetPrompt; break;
- case kSetPrompt: RoutineToCall=ExampleSetPrompt; break;
- case kGetIconData: RoutineToCall=ExampleGetIconData; break;
- case kGetEditMenuState: RoutineToCall=ExampleGetEditMenuState; break;
- case kSetOrigin: RoutineToCall=ExampleSetOrigin; break;
- case kExtractHelpItem: RoutineToCall=ExampleExtractHelpItem; break;
- default: return 0;
- }
- }
- result=CallComponentFunctionWithStorage(storage, params, RoutineToCall);
-
- return result;
- }
-
- /*
- * open our instance. We allocate our storage handle here but do not allocate anything inside it.
- * This is because we aren't necessarily being opened for real (but just for addition to the More
- * Choices list, etc.). We probably should not even allocate our storage handle here, but wait
- * for the InitPicker message.
- */
- pascal ComponentResult ExampleOpen(PickerStorageHndl storage, ComponentInstance self)
- {
-
- storage = (PickerStorageHndl) NewHandle(sizeof(PickerStorage));
- SetComponentInstanceStorage(self,(Handle) storage);
- (*storage)->myself=self; // store reference to self
- (*storage)->realPicker = false; // we're not real yet
-
- return 0;
- }
-
- pascal ComponentResult ExampleClose(PickerStorageHndl storage, ComponentInstance self)
- {
- #pragma unused (self)
-
- // if we have been opened for real, dispose of our private data
- if((*storage)->realPicker) {
- DisposPixPat((*storage)->newColorPat);
- DisposPixPat((*storage)->origColorPat);
- DisposHandle((Handle) (*storage)->profile);
- }
-
- DisposHandle((Handle) storage); // remove all storage
-
- return noErr;
- }
-
- pascal ComponentResult ExampleCanDo(PickerStorageHndl storage, short selector)
- {
- #pragma unused (storage)
-
- if ((selector >= kComponentTargetSelect) && (selector <= kComponentOpenSelect))
- return true;
- if ((selector >= kInitPicker) && (selector <= kSetOrigin))
- return true;
-
- return false;
- }
-
- pascal ComponentResult ExampleVersion(PickerStorageHndl storage)
- {
- #pragma unused (storage)
-
- return 0;
- }
-
- pascal ComponentResult ExampleRegister(PickerStorageHndl storage)
- {
- #pragma unused (storage)
-
- return noErr; // always register
- }
-
- pascal ComponentResult ExampleSetTarget(PickerStorageHndl storage, ComponentInstance topOfCallChain)
- {
- #pragma unused (storage,topOfCallChain)
-
- return 0;
- }
-
- /*
- * Test the machine state and picker supplied instance flags (restrictions) to check to see if
- * we can live here. If not, return an error.
- */
- pascal long ExampleTestGraphicsWorld(PickerStorageHndl storage,PickerInitData *data)
- {
- #pragma unused(storage,data)
- OSErr err = noErr;
- long gLong;
-
- // we require at least Color QuickDraw
-
- Gestalt(gestaltQuickdrawVersion,&gLong);
-
- return gLong >= gestalt8BitQD ? noErr : pickerCantLive;
- }
-
- pascal ComponentResult ExampleInitPicker(PickerStorageHndl storage,PickerInitData *data)
- {
- GrafPtr thePort;
- OSErr error = noErr;
- PMColorPtr theColor;
- RGBColor rgb;
- short resFile;
-
- // open our resource file
- resFile = OpenComponentResFile((Component) (*storage)->myself);
-
- GetPort(&thePort);
- (*storage)->port = thePort;
- (*storage)->flags = data->flags;
-
- (*storage)->realPicker = true;
-
- // we're always opened invisible
- (*storage)->visible = false;
-
- (*storage)->active = true;
-
- // initalise our internal colors
- theColor = &(*storage)->color;
- theColor->profile = 0;
- theColor->color.rgb.red = 0;
- theColor->color.rgb.green = 0;
- theColor->color.rgb.blue = 0;
- (*storage)->origColor = (*storage)->color;
- (*storage)->lastRGB = (*storage)->color.color.rgb;
-
- InitNumerics(storage);
-
- // allocate patterns for the color rectangles
- (*storage)->newColorPat = NewPixPat();
- (*storage)->origColorPat = NewPixPat();
-
- // and initialise them to the current color
- rgb = (*storage)->color.color.rgb;
- MakeRGBPat((*storage)->newColorPat,&rgb);
-
- rgb = (*storage)->origColor.color.rgb;
- MakeRGBPat((*storage)->origColorPat,&rgb);
-
- (*storage)->profile = 0L;
-
- finish:
- CloseComponentResFile(resFile);
-
- return error;
- }
-
- /*
- * Return a pointer to our private dialog if we have one. This example does not, so we
- * return nil.
- */
- pascal ComponentResult ExampleGetDialog(PickerStorageHndl storage)
- {
- #pragma unused (storage)
-
- // if you did have a dialog, you would open up your resource file,
- // open up the dialog and detach any private resources that were grabbed from
- // your file (such as the WDEF if you had a private one).
-
- return 0L;
- }
-
- /*
- * Return a handle to the picker's item list. If the picker saved it as a resource, it is
- * the picker's responsibility to detach it
- */
- pascal long ExampleGetItemList(PickerStorageHndl storage)
- {
- #pragma unused (storage)
- Handle theItems;
- short resFile;
-
- // open our resource file so we can get our DITL
- resFile = OpenComponentResFile((Component) (*storage)->myself);
-
- // get the DITL and detach it so it won't go away when we close the file
- theItems = GetResource('DITL',kPickerDITL);
- if(theItems)
- DetachResource(theItems);
-
- // close the file
- CloseComponentResFile(resFile);
-
- return (long) theItems;
- }
-
- /*
- * Get the current original or new color
- */
- pascal ComponentResult ExampleGetColor(PickerStorageHndl storage,ColorType whichColor,PMColorPtr color)
- {
- // we can copy the color here because the profile is always set to what we want it to be
- // (nil - the system profile/rgb space).
- if(whichColor == kNewColor)
- *color = (*storage)->color;
- else
- *color = (*storage)->origColor;
-
-
- return noErr;
- }
-
- /*
- * Set the current original or new color.
- */
- pascal ComponentResult ExampleSetColor(PickerStorageHndl storage,ColorType whichColor,PMColorPtr color)
- {
- Boolean updateEditor = false;
- Boolean textInvalid = false;
- CWorld cworld;
- PMColor myColor;
- long csLong;
- OSErr err = noErr;
-
- myColor = *color; // get our own copy
-
- // check to see if a profile was included, if so, convert the color to system space
- if(color->profile) {
- // first make sure that ColorSync is around
- if(Gestalt(gestaltColorMatchingVersion,&csLong) != noErr) {
- err = colorSyncNotInstalled;
- goto fail;
- }
-
- // now create the color world and convert the color
- if(CWNewColorWorld(&cworld,myColor.profile,0L) == noErr) {
- if(CWMatchColors(cworld,&myColor.color,1) != noErr) {
- err = badProfileError;
- CWDisposeColorWorld(cworld);
- goto fail;
- }
- CWDisposeColorWorld(cworld);
- } else {
- err = badProfileError;
- goto fail;
- }
- }
- myColor.profile = 0L; // it's in the system space now
-
- if(whichColor == kNewColor) {
- (*storage)->color = *color;
- (*storage)->lastRGB = color->color.rgb;
- updateEditor = true;
- } else {
- (*storage)->origColor = *color;
-
- // make a new pattern for the original color
- MakeRGBPat((*storage)->origColorPat,&color->color.rgb);
- if((*storage)->visible)
- DrawColorRects(storage,true); // redraw the original color rectangle
- }
-
- if(updateEditor) {
- // make some internal calls to update data structures and redraw the parts of the picker
- // that need it
- SetSelectionColor(storage);
- UpdateColorText(storage);
-
- if((*storage)->visible) {
- // we don't call DoPickerDraw here as we don't need to redraw everything!
- DrawColorRects(storage,false);
- DrawColorEditor(storage,false);
- }
- }
- fail:
- return err;
- }
-
- /*
- * Change our visibility status
- */
- pascal ComponentResult ExampleSetVisibility(PickerStorageHndl storage,Boolean visible)
- {
-
- (*storage)->visible = visible;
-
- return 0L;
- }
-
- /*
- * Redraw the picker (in response to an update event).
- */
- pascal ComponentResult ExampleDisplayPicker(PickerStorageHndl storage)
- {
-
- if((*storage)->visible) {
- DrawColorList(storage);
- DrawColorEditor(storage,true);
- }
-
- return noErr;
- }
-
- /*
- * Do any special preprocessing for events that we need to do.
- */
- pascal ComponentResult ExampleDoEvent(PickerStorageHndl storage,EventData *data)
- {
- OSErr err = noErr;
-
- // initialise to not filter
- data->handled = false;
- data->action = kDidNothing;
-
- if(data->event) {
- switch(data->event->what) {
- case nullEvent:
- DoIdle(storage,data);
- break;
- case mouseDown:
- err = DoMouseDown(storage,data);
- break;
- case keyDown:
- case autoKey:
- err = DoKeyDown(storage,data);
- break;
- case keyUp:
- err = DoKeyUp(storage,data);
- break;
- case activateEvt:
- if(data->event->modifiers & activeFlag)
- ActivatePicker(storage);
- else
- DeactivatePicker(storage);
- break;
- }
- }
- return err;
- }
-
- /*
- * Handle edit operations. We let the picker manager handle everything for us, except undo.
- */
- pascal ComponentResult ExampleDoEdit(PickerStorageHndl storage,EditData *data)
- {
- RGBColor rgb;
-
- switch(data->theEdit) {
- default:
- // default behaviour is ok
- data->action = kDidNothing;
- data->handled = false;
- break;
- case kUndo:
- // do the undo thing
- rgb = (*storage)->lastRGB;
- (*storage)->lastRGB = (*storage)->color.color.rgb;
- (*storage)->color.color.rgb = rgb;
-
- // update the other internal data and then redraw
- SetSelectionColor(storage);
- UpdateColorText(storage);
- DrawColorRects(storage,false);
-
- data->action = kColorChanged;
- data->handled = true;
- break;
- }
- return noErr;
- }
-
- /*
- * The dialog manager said that one of our items was hit, so find out which one
- * it was and do the right thing.
- */
- pascal long ExampleItemHit(PickerStorageHndl storage,ItemHitData *data)
- {
- #pragma unused(iMod)
-
- Handle theItem;
- short iType;
- Rect iBox;
- OSErr err = noErr;
-
- data->action = kDidNothing;
-
- GetDItem((*storage)->port,(*storage)->baseItem + data->itemHit,&iType,&theItem,&iBox);
-
- switch(data->itemHit) {
- case iRedText:
- case iGreenText:
- case iBlueText:
- // don't udpate everything as the user types each key, just do it when they
- // leave a field
- if(data->iMod != kKeyDown && data->itemHit != kMouseDown)
- CheckCurrentWorld(storage,data->itemHit);
- break;
- case iOrigColor:
- err = DoListClick(storage,data);
- break;
- case iNewColor:
- break;
- }
- return err;
- }
-
- /*
- * Set the base item for the color picker's items. This allows us to get at our items
- * through the dialog manager. RealItemNumber = baseItem + locaItemNumber (1 based).
- */
- pascal long ExampleSetBaseItem(PickerStorageHndl storage,short baseItem)
- {
- (*storage)->baseItem = baseItem;
-
- return noErr;
- }
-
- /*
- * Get the current destination profile our picker is using
- */
- pascal long ExampleGetProfile(PickerStorageHndl storage)
- {
- Handle h;
-
- // return a copy of the profile
- h = (Handle) (*storage)->profile;
- if(h)
- HandToHand(&h);
-
- return (long) h;
- }
-
- /*
- * Set the current destination profile.
- */
- pascal long ExampleSetProfile(PickerStorageHndl storage,CMProfileHandle profile)
- {
- CMProfileHandle myProfile;
- OSErr err = noErr;
-
- // make a private copy of the profile. We need to do this even though this
- // picker doesn't do anything with profiles because the picker manager relies
- // on us to store this data so that it doesn't have to duplicate the storage
- // and waste lots of memory
-
- if(myProfile = profile) {
- HandToHand((Handle *) &myProfile);
- if((err = MemError()) != noErr)
- goto fail;
- }
- (*storage)->profile = myProfile;
-
- fail:
- return err;
- }
-
- /*
- * Get the contents of our prompt
- */
- pascal long ExampleGetPrompt(PickerStorageHndl storage,Str255 prompt)
- {
- Handle theItem;
- short iType;
- Rect iBox;
-
- GetDItem((*storage)->port,(*storage)->baseItem + iPrompt,&iType,&theItem,&iBox);
- GetIText(theItem,prompt);
-
- return noErr;
- }
-
- /*
- * Set the contents of our prompt
- */
- pascal long ExampleSetPrompt(PickerStorageHndl storage,Str255 prompt)
- {
- Handle theItem;
- short iType;
- Rect iBox;
-
- GetDItem((*storage)->port,(*storage)->baseItem + iPrompt,&iType,&theItem,&iBox);
- SetIText(theItem,prompt);
-
- return noErr;
- }
-
- /*
- * Return the data that the picker manager needs for our picker in the More Choices
- * List - our script code and the resource id of our icon suite.
- */
- pascal long ExampleGetIconData(PickerStorageHndl storage,PickerIconData *data)
- {
- short fref;
- OSErr err = noErr;
- PickerIconData **mypdat;
-
- data->scriptCode = 0;
- data->iconSuiteID = kPickerData;
-
- fref = OpenComponentResFile((Component) (*storage)->myself);
- if(fref) {
- mypdat = (PickerIconData **) GetResource(kPickerDataType,kPickerData);
- if(mypdat)
- *data = **mypdat;
- else
- goto fail;
- } else
- goto fail;
-
- CloseComponentResFile(fref);
-
- return err;
-
- fail:
- DebugStr("\pProblem getting resource");
-
- return pickerResourceError;
- }
-
- /*
- * Specify how we want the edit menu to be set
- */
- pascal long ExampleGetEditMenuState(PickerStorageHndl storage,MenuState *mState)
- {
- #pragma unused(storage)
-
- OSErr err = noErr;
-
- mState->cutEnabled = true;
- mState->copyEnabled = true;
- mState->pasteEnabled = true;
- mState->clearEnabled = true;
- mState->undoEnabled = true;
- strcpy(mState->undoString,"\pUndo");
-
- return err;
- }
-
-
- /*
- * We've been moved to the specified origin. Update any internal data structures here.
- * All of our dialog items will have been moved for us.
- */
- pascal long ExampleSetOrigin(PickerStorageHndl storage,Point where)
- {
- #pragma unused(storage,where)
-
- // we don't have anything that needs moving
-
- return noErr;
- }
-
- /*
- * The picker manager is about to put up a help balloon for a given item. If we want to overide
- * any help resources that we have, we should store the help item info in helpInfo and return
- * noErr. Otherwise return noHelpForItem and the default behaviour will take place.
- */
- pascal long ExampleExtractHelpItem(PickerStorageHndl storage,short itemNo,short whichState,HelpItemInfo *helpInfo)
- {
- #pragma unused(storage,itemNo,whichState,helpInfo)
-
- return noHelpForItem;
- }
-
-
-
- /****************************************************************************************************
- *
- * Private routines begin here
- *
- ****************************************************************************************************/
-
-
- /*
- * Do anything special for a mousedown event.
- */
- OSErr DoMouseDown(PickerStorageHndl storage,EventData *data)
- {
- #pragma unused (storage,data)
-
- // set data->handled to true if we handled the event
-
- return noErr;
- }
-
- /*
- * Do anything special for a keydown event.
- */
- OSErr DoKeyDown(PickerStorageHndl storage,EventData *data)
- {
- short key;
- Boolean optKeyDown,cmdKeyDown,itemOurs;
- short theItem;
-
- // check that the current edit item is ours and that the command and option keys are
- // not down before we do any key masking
-
- theItem = ((DialogPeek) (*storage)->port)->editField + 1 - (*storage)->baseItem;
- optKeyDown = (data->event->modifiers & optionKey) != 0;
- cmdKeyDown = (data->event->modifiers & cmdKey) != 0;
- itemOurs = theItem > 0 && theItem <= iLastItem;
-
- if(!optKeyDown && !cmdKeyDown && itemOurs) {
- key = data->event->message & charCodeMask;
- switch(key) {
- case kUpArrow:
- case kDnArrow:
- case kLtArrow:
- case kRtArrow:
- case '.':
- case kBackSpace:
- case kTab:
- // these keys are all ok
- break;
-
- case kReturn:
- case kEnter:
- // make sure we update everything
- CheckCurrentWorld(storage,iRedText);
- CheckCurrentWorld(storage,iGreenText);
- CheckCurrentWorld(storage,iBlueText);
- break;
- default:
- // check that the key was numeric, otherwise beep and handle the keydown
- // note that this is not internationally kosher! (that's why this is an example!)
- if(key < '0' || key > '9') {
- SysBeep(1);
- data->handled = true;
- }
- break;
- }
- }
-
- return noErr;
- }
-
- /*
- * Do anything special for a keyup event.
- */
- OSErr DoKeyUp(PickerStorageHndl storage,EventData *data)
- {
- #pragma unused (storage,data)
-
- return noErr;
- }
-
- /*
- * Do anything special for a null event.
- */
- OSErr DoIdle(PickerStorageHndl storage,EventData *data)
- {
- #pragma unused (storage,data)
-
- return noErr;
- }
-
- /*
- * Handle an activate event.
- */
- void ActivatePicker(PickerStorageHndl storage)
- {
- (*storage)->active = true;
- }
-
- /*
- * Handle an deactivate event.
- */
- void DeactivatePicker(PickerStorageHndl storage)
- {
- (*storage)->active = false;
- }
-
- /*
- * check the item "itemNo" to see if it's changed. If it has, then update
- * the current color and recreate the item's string so that it looks pretty.
- * We use a macro CheckBigEnough to make sure that the difference between
- * string and number is greater than the error in the string representation.
- */
- void CheckCurrentWorld(PickerStorageHndl storage,short itemNo)
- {
- Str255 itemStr;
- Handle theItem;
- long value;
- Boolean drawWheel = false,newColor = false;
-
- theItem = GetItemHandle(storage,itemNo);
- switch(itemNo) {
- case iRedText:
- GetIText(theItem,itemStr);
- if(PercentageToNum(storage,itemStr,&value) && ChangeBigEnough(value,(*storage)->color.color.rgb.red)) {
- (*storage)->lastRGB = (*storage)->color.color.rgb;
- (*storage)->color.color.rgb.red = value;
- newColor = true;
- }
- break;
- case iGreenText:
- GetIText(theItem,itemStr);
- if(PercentageToNum(storage,itemStr,&value) && ChangeBigEnough(value,(*storage)->color.color.rgb.green)) {
- (*storage)->lastRGB = (*storage)->color.color.rgb;
- (*storage)->color.color.rgb.green = value;
- newColor = true;
- }
- break;
- case iBlueText:
- GetIText(theItem,itemStr);
- if(PercentageToNum(storage,itemStr,&value) && ChangeBigEnough(value,(*storage)->color.color.rgb.blue)) {
- (*storage)->lastRGB = (*storage)->color.color.rgb;
- (*storage)->color.color.rgb.blue = value;
- newColor = drawWheel = true;
- }
- break;
- }
- if(newColor) {
- SetSelectionColor(storage);
- UpdateColorText(storage);
- }
- }
-
- /*
- * Update the text fields based on string comparisons of the current internal color (numeric)
- * to the contents of the dialog items.
- */
- void UpdateColorText(PickerStorageHndl storage)
- {
- Str255 numStr,itemStr;
- Handle theItem;
- short iType;
- short itemNo;
- Rect iBox;
-
- TextMode(srcCopy);
- ForeColor(blackColor);
- BackColor(whiteColor);
-
- // Red
-
- GetDItem((*storage)->port,(*storage)->baseItem + iRedText,&iType,&theItem,&iBox);
- NumToPercentage(storage,(*storage)->color.color.rgb.red,numStr);
- numStr[numStr[0] + 1] = '\0';
- GetIText(theItem,itemStr);
- itemStr[itemStr[0] + 1] = '\0';
-
- if(strcmp(itemStr,numStr) != 0)
- SetIText(theItem,numStr);
-
- // Green
-
- GetDItem((*storage)->port,(*storage)->baseItem + iGreenText,&iType,&theItem,&iBox);
- NumToPercentage(storage,(*storage)->color.color.rgb.green,numStr);
- numStr[numStr[0] + 1] = '\0';
- GetIText(theItem,itemStr);
- itemStr[itemStr[0] + 1] = '\0';
-
- if(strcmp(itemStr,numStr) != 0)
- SetIText(theItem,numStr);
-
- // Blue
-
- GetDItem((*storage)->port,(*storage)->baseItem + iBlueText,&iType,&theItem,&iBox);
- NumToPercentage(storage,(*storage)->color.color.rgb.blue,numStr);
- numStr[numStr[0] + 1] = '\0';
- GetIText(theItem,itemStr);
- itemStr[itemStr[0] + 1] = '\0';
-
- if(strcmp(itemStr,numStr) != 0)
- SetIText(theItem,numStr);
-
- // now select the current text item (if it's ours...)
-
- itemNo = ((DialogPeek) (*storage)->port)->editField + 1 - (*storage)->baseItem;
- if(itemNo > 0 && itemNo >= iLastItem)
- SelIText((*storage)->port,itemNo,0,32767);
- }
-
- /*
- * Convert a value to a percentage of 65536 and write it as a string to theString. We use
- * the script manager cuz we're nice.
- */
- void NumToPercentage(PickerStorageHndl storage,long value,char *theString)
- {
- short fResult;
-
- HLock((Handle) storage);
-
- fResult = FormatX2Str(value / 65535.0 * 100.0,&(*storage)->nFormat,&(*storage)->nParts,theString);
- if(fResult != fFormatOK)
- DebugStr("\pBad format");
-
- HUnlock((Handle) storage);
- }
-
- /*
- * Convert a percentage string (percentage of 65535) to a number. Return true if the script
- * manager was able to successfuly convert, false otherwise (ie the string was not a number).
- */
- Boolean PercentageToNum(PickerStorageHndl storage,char *theString,long *theNum)
- {
- extended x;
- FormatStatus fResult;
- Boolean isValid = false;
-
- HLock((Handle) storage);
- fResult = FormatStr2X((ConstStr255Param) theString,&(*storage)->nFormat,&(*storage)->nParts,&x);
- HUnlock((Handle) storage);
-
- switch(fResult) {
- case fFormatOK:
- case fBestGuess:
- case fOutOfSynch:
- case fSpuriousChars:
- case fMissingDelimiter:
- case fExtraDecimal:
- case fMissingLiteral:
- case fExtraExp:
- case fExtraPercent:
- case fExtraSeparator:
- case fEmptyFormatString:
- isValid = true;
- break;
- default:
- break;
- }
- if(isValid) {
- *theNum = x * 65535.0 / 100.0;
- if(*theNum > 65535)
- *theNum = 65535;
- else if(*theNum < 0)
- *theNum = 0;
- }
- return isValid;
- }
-
- /*
- * Handle a click in the original and new color rectangles. If the user has clicked
- * in the original color box, we want to make that color the new collor.
- */
- OSErr DoListClick(PickerStorageHndl storage,ItemHitData *data)
- {
- Rect origColorRect;
- Boolean inBox,lastInBox;
- PMColor origTemp,newTemp;
- Point where;
- PMColor newColor;
- OSErr err = noErr;
-
- GetItemRect(storage,iOrigColor,&origColorRect);
-
- inBox = true;
- lastInBox = false;
-
- origTemp = (*storage)->origColor;
- newTemp = (*storage)->color;
-
- do {
- GetMouse(&where);
- inBox = PtInRect(where,&origColorRect);
- if(inBox != lastInBox) {
- lastInBox = inBox;
- if(inBox)
- (*storage)->color = origTemp;
- else
- (*storage)->color = newTemp;
- SetSelectionColor(storage);
- DrawColorRects(storage,true);
- UpdateColorText(storage);
-
- if(data->colorProc) {
- newColor.color = (*storage)->color.color;
- newColor.profile = 0L;
- data->colorProc(data->colorProcData,&newColor);
- }
- }
- } while(Button());
- if(inBox) {
- data->action = kColorChanged;
- (*storage)->color = origTemp;
- }
- return err;
- }
-
- /*
- * Draws the color editor (for example, a color wheel). scrnInvalid specifies
- * whether the screen itself is invalid, or we're just updating for a new color
- * selection. This allows this routine to be used for more than just Window
- * updates.
- */
- void DrawColorEditor(PickerStorageHndl storage,Boolean scrnInvalid)
- {
- #pragma unused(storage,scrnInvalid)
-
- // we don't do anything here in this example
- }
-
- /*
- * This routine redraws the entire original and new color rectangles. It is called
- * when the dialog needs to be updated.
- */
- void DrawColorList(PickerStorageHndl storage)
- {
- Rect r;
- PenState oldPen;
-
- GetPenState(&oldPen);
- PenNormal();
- ForeColor(blackColor);
-
- GetItemRect(storage,iOrigColor,&r);
- FrameRect(&r);
-
- GetItemRect(storage,iNewColor,&r);
- FrameRect(&r);
-
- // now draw the interior of both the original and new color rectangles
- DrawColorRects(storage,true);
-
- ForeColor(blackColor);
- SetPenState(&oldPen);
- }
-
- /*
- * Draw the original and new color rectangles. We usually only draw the new color
- * rectangle, so we have a boolean parameter for whether or not we want to draw
- * the original color. Note that this routine only draws the interior of the
- * rectangles. It is designed to be called inside a loop where the current color
- * is being changed rapidly and not for entire dialog updates.
- */
- void DrawColorRects(PickerStorageHndl storage,Boolean drawOrig)
- {
- Rect r;
-
- PenNormal();
- GetItemRect(storage,iOrigColor,&r);
- InsetRect(&r,1,1);
-
- if(drawOrig)
- FillCRect(&r,(*storage)->origColorPat);
-
- GetItemRect(storage,iNewColor,&r);
- InsetRect(&r,1,1);
-
- FillCRect(&r,(*storage)->newColorPat);
- }
-
- /*
- * Take the current color and make a new RGB pattern for it
- */
- void SetSelectionColor(PickerStorageHndl storage)
- {
- RGBColor rgb;
-
- rgb = (*storage)->color.color.rgb;
- MakeRGBPat((*storage)->newColorPat,&rgb);
-
- DrawColorRects(storage,false);
- }
-
- /*
- * init the data we use for the script manager for our string conversion stuff
- */
- void InitNumerics(PickerStorageHndl storage)
- {
- Itl4Handle itl4;
- StringHandle nString;
- short resFile;
-
- resFile = OpenComponentResFile((Component) (*storage)->myself);
-
- itl4 = (Itl4Handle)IUGetIntl(4);
-
- if (itl4) {
- (*storage)->nParts = *((NumberPartsPtr)( (char *)(*itl4) +
- ((*itl4)->defPartsOffset ) ) );
- } else
- DebugStr("\p unable to get default format");
-
- nString = GetString(kPercFormatString);
- if(!nString)
- DebugStr("\pCan't get format string");
-
- MoveHHi((Handle) storage);
- HLock((Handle) storage);
- MoveHHi((Handle) nString);
- HLock((Handle) nString);
-
- if(Str2Format(*nString,&(*storage)->nParts,&(*storage)->nFormat) != fFormatOK)
- DebugStr("Str2Format for nFormat failed");
-
- HUnlock((Handle) nString);
- ReleaseResource((Handle) nString);
-
- HUnlock((Handle) storage);
-
- CloseComponentResFile(resFile);
- }
-
-
-
- /*******************************************************************************************************
- *
- * These are some utillity routines that make the dialog manager easier to work with.
- *
- *******************************************************************************************************/
-
- /*
- * Return true if the given point is within the specified dialog item.
- */
- Boolean PtInItem(PickerStorageHndl storage, Point where, short itemNo)
- {
- Rect iBox;
-
- GetItemRect(storage,itemNo,&iBox);
-
- return PtInRect(where,&iBox);
- }
-
- /*
- * Get the rectangle for the specified item (itemNo is a local item number, so this routines
- * adds in the picker's base item number before calling GetDItem).
- */
- void GetItemRect(PickerStorageHndl storage,short itemNo,Rect *r)
- {
- Handle theItem;
- short iType;
-
- GetDItem((*storage)->port,(*storage)->baseItem + itemNo,&iType,&theItem,r);
- }
-
- void SetItemRect(PickerStorageHndl storage,short itemNo,Rect *r)
- {
- Handle theItem;
- short iType;
- Rect iBox;
-
- GetDItem((*storage)->port,(*storage)->baseItem + itemNo,&iType,&theItem,&iBox);
- SetDItem((*storage)->port,(*storage)->baseItem + itemNo,iType,theItem,r);
- }
-
- void OffsetItemRect(PickerStorageHndl storage,short itemNo,short h,short v)
- {
- Handle theItem;
- Rect r;
- short iType;
-
- GetDItem((*storage)->port,(*storage)->baseItem + itemNo,&iType,&theItem,&r);
-
- OffsetRect(&r,h,v);
- SetDItem((*storage)->port,(*storage)->baseItem + itemNo,iType,theItem,&r);
- }
-
- Handle GetItemHandle(PickerStorageHndl storage,short theItem)
- {
- Handle itemH;
- short iType;
- Rect iBox;
-
- GetDItem((*storage)->port,(*storage)->baseItem + theItem,&iType,&itemH,&iBox);
-
- return itemH;
- }
-